using Prism.Commands;
using Prism.Mvvm;
using Satellite_Calculation;
using SatelliteUI.Models;
using System;
using System.Collections.Generic;
using System.Globalization;

namespace SatelliteUI.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private string _title = "GPS卫星位置计算";
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        private string outText;
        public string OutText
        {
            get { return outText; }
            set { SetProperty(ref outText, value); }
        }


        #region 变量对象
        public Variable miu { get; } = new Variable("地球引力场参数", "μ", "", "m³/s²", typeof(decimal));
        public Variable ohme { get; } = new Variable("地球自转角速度", "Ωe", "", "rad/s", typeof(decimal));
        public Variable toc { get; } = new Variable("参考时刻对应GPS周内秒", "Toc", "", "s", typeof(decimal));
        public Variable toe { get; } = new Variable("参考时刻", "Toe", "", "s", typeof(decimal));
        public Variable t1 { get; } = new Variable("观测时刻对应GPS周内秒", "T'", "", "s", typeof(decimal));
        public Variable a0 { get; } = new Variable("时钟修正0", "a0", "", "s", typeof(decimal));
        public Variable a1 { get; } = new Variable("时钟修正1", "a1", "", "/", typeof(decimal));
        public Variable a2 { get; } = new Variable("时钟修正2", "a2", "", "1/s", typeof(decimal));
        public Variable sqrta { get; } = new Variable("轨道半长轴算术平方根", "√a", "", "√m", typeof(decimal));
        public Variable e { get; } = new Variable("轨道离心率", "E", "", "/", typeof(decimal));
        public Variable i0 { get; } = new Variable("参考时刻轨道倾角", "I0", "", "rad", typeof(decimal));
        public Variable ohm0 { get; } = new Variable("升交点经度", "Ω0", "", "rad", typeof(decimal));
        public Variable omega { get; } = new Variable("近地点幅角", "ω", "", "rad", typeof(decimal));
        public Variable m0 { get; } = new Variable("参考时刻平均近点角", "M0", "", "rad", typeof(decimal));
        public Variable di_dt { get; } = new Variable("倾角变化率", "Δi/Δt", "", "rad/s", typeof(decimal));
        public Variable ohm_dot { get; } = new Variable("升交点经度的变化率", "Ω_", "", "rad/s", typeof(decimal));
        public Variable delta_n { get; } = new Variable("平均角速度的校正值", "Δn", "", "rad", typeof(decimal));
        public Variable cuc { get; } = new Variable("纬度幅角余弦的校正值", "Cuc", "", "rad", typeof(decimal));
        public Variable cus { get; } = new Variable("纬度幅角正弦的校正值", "Cus", "", "rad", typeof(decimal));
        public Variable cic { get; } = new Variable("倾角余弦的校正值", "Cic", "", "rad", typeof(decimal));
        public Variable cis { get; } = new Variable("倾角正弦的校正值", "Cis", "", "rad", typeof(decimal));
        public Variable crc { get; } = new Variable("轨道半径余弦的校正值", "Crc", "", "m", typeof(decimal));
        public Variable crs { get; } = new Variable("轨道半径正弦的校正值", "Crs", "", "m", typeof(decimal));        public Variable kplprecision { get; } = new Variable("开普勒方程迭代精度", "E_Precision", "", "/", typeof(decimal));
        public Variable pointprecision { get; } = new Variable("坐标值输出精度", "P_Precision", "", "位", typeof(int));
        #endregion

        #region 绑定对象
        private string _miu;
        public string Miu
        {
            get { return _miu; }
            set { SetProperty(ref _miu, value); miu.Value = value; }
        }
        private string _ohme;
        public string Ohme
        {
            get { return _ohme; }
            set { SetProperty(ref _ohme, value); ohme.Value = value; }
        }
        private string _toc;
        public string Toc
        {
            get { return _toc; }
            set { SetProperty(ref _toc, value); ReportVariables[0].Value = value; }
        }
        private string _toe;
        public string Toe
        {
            get { return _toe; }
            set { SetProperty(ref _toe, value); ReportVariables[1].Value = value; }
        }
        private string _t1;
        public string T1
        {
            get { return _t1; }
            set { SetProperty(ref _t1, value); ReportVariables[2].Value = value; }
        }
        private string _a0;
        public string A0
        {
            get { return _a0; }
            set { SetProperty(ref _a0, value); ReportVariables[3].Value = value; }
        }
        private string _a1;
        public string A1
        {
            get { return _a1; }
            set { SetProperty(ref _a1, value); ReportVariables[4].Value = value; }
        }
        private string _a2;
        public string A2
        {
            get { return _a2; }
            set { SetProperty(ref _a2, value); ReportVariables[5].Value = value; }
        }
        private string _sqrta;
        public string Sqrta
        {
            get { return _sqrta; }
            set { SetProperty(ref _sqrta, value); ReportVariables[6].Value = value; }
        }
        private string _e;
        public string E
        {
            get { return _e; }
            set { SetProperty(ref _e, value); ReportVariables[7].Value = value; }
        }
        private string _i0;
        public string I0
        {
            get { return _i0; }
            set { SetProperty(ref _i0, value); ReportVariables[8].Value = value; }
        }
        private string _ohm0;
        public string Ohm0
        {
            get { return _ohm0; }
            set { SetProperty(ref _ohm0, value); ReportVariables[9].Value = value; }
        }
        private string _omega;
        public string Omega
        {
            get { return _omega; }
            set { SetProperty(ref _omega, value); ReportVariables[10].Value = value; }
        }
        private string _m0;
        public string M0
        {
            get { return _m0; }
            set { SetProperty(ref _m0, value); ReportVariables[11].Value = value; }
        }
        private string _di_dt;
        public string dI_dT
        {
            get { return _di_dt; }
            set { SetProperty(ref _di_dt, value); ReportVariables[12].Value = value; }
        }
        private string _ohm_dot;
        public string Ohm_dot
        {
            get { return _ohm_dot; }
            set { SetProperty(ref _ohm_dot, value); ReportVariables[13].Value = value; }
        }
        private string _delta_n;
        public string delta_N
        {
            get { return _delta_n; }
            set { SetProperty(ref _delta_n, value); ReportVariables[14].Value = value; }
        }
        private string _cuc;
        public string Cuc
        {
            get { return _cuc; }
            set { SetProperty(ref _cuc, value); ReportVariables[15].Value = value; }
        }
        private string _cus;
        public string Cus
        {
            get { return _cus; }
            set { SetProperty(ref _cus, value); ReportVariables[16].Value = value; }
        }
        private string _cic;
        public string Cic
        {
            get { return _cic; }
            set { SetProperty(ref _cic, value); ReportVariables[17].Value = value; }
        }
        private string _cis;
        public string Cis
        {
            get { return _cis; }
            set { SetProperty(ref _cis, value); ReportVariables[18].Value = value; }
        }
        private string _crc;
        public string Crc
        {
            get { return _crc; }
            set { SetProperty(ref _crc, value); ReportVariables[19].Value = value; }
        }
        private string _crs;
        public string Crs
        {
            get { return _crs; }
            set { SetProperty(ref _crs, value); ReportVariables[20].Value = value; }
        }
        private string _kplprecision;
        public string Kplprecision
        {
            get { return _kplprecision; }
            set { SetProperty(ref _kplprecision, value); kplprecision.Value = value; }
        }
        private string _pointprecision;
        public string Pointprecision
        {
            get { return _pointprecision; }
            set { SetProperty(ref _pointprecision, value); pointprecision.Value = value; }
        }
        #endregion

        private List<Variable> ReportVariables { get; set; }
        private List<decimal> v = new List<decimal>();

        public DelegateCommand RunCommand { get; private set; }
        public DelegateCommand LoadCommand { get; private set; }
        public DelegateCommand ClearCommand { get; private set; }

        public MainWindowViewModel()
        {
            ReportVariables = new List<Variable>()
            {
                toc, toe, t1, a0, a1, a2, sqrta, e,
                i0, ohm0, omega, m0, di_dt, ohm_dot, delta_n,
                cuc, cus, cic, cis, crc, crs
            };
            RunCommand = new DelegateCommand(ExecuteRun);
            LoadCommand = new DelegateCommand(ExecuteLoad);
            ClearCommand = new DelegateCommand(() => { OutText = string.Empty; });
        }

        private void ExecuteRun()
        {
            SendMessage("正在开始计算...");
            decimal temp;
            foreach (var item in ReportVariables)
            {
                if (decimal.TryParse(item.Value, NumberStyles.Float, null, out temp))
                    v.Add(temp);
                else
                {
                    SendMessage(item.ToString() + "取值不符合要求, 计算已经停止");
                    return;
                }
            }
            SendMessage("所有变量取值均合法, 开始计算");
            try
            {
                string details = string.Empty;
                var result = new SatelliteCalculator(decimal.Parse(miu.Value, NumberStyles.Float),
                    decimal.Parse(ohme.Value, NumberStyles.Float), decimal.Parse(kplprecision.Value, NumberStyles.Float),
                    int.Parse(pointprecision.Value, NumberStyles.Float)).Calculate(new Report(v), ref details);
                SendMessage("计算过程：\n" + details);
                result.Precision = int.Parse(pointprecision.Value);
                SendMessage("计算结果：\n\n" + result.ToString() + "\n");
                SendMessage("计算完成！");
            }
            catch (Exception ex)
            {
                SendMessage(ex.Message);
            }
        }

        private void ExecuteLoad()
        {
            Miu = "3.986005e14";
            Ohme = "7.2921151467e-5";
            Kplprecision = "1e-6";
            Pointprecision = "2";
            Toc = "0";
            Toe = "0";
            T1 = "4800";
            A0 = "0.000286006834358";
            A1 = "1.70530256582e-12";
            A2 = "0";
            Sqrta = "5153.71277046";
            E = "0.00531007151585";
            I0 = "0.974329277388";
            Ohm0 = "-2.90801277219";
            Omega = "-1.68194462925";
            M0 = "1.22639730096";
            dI_dT = "1.8643633725e-010";
            Ohm_dot = "-7.71246411223e-009";
            delta_N = "4.11159983607e-009";
            Cuc = "-5.52646815777e-006";
            Cus = "1.11926347017e-005";
            Cic = "-9.685754776e-008";
            Cis = "-7.82310962677e-008";
            Crc = "175.34375";
            Crs = "-105.4375";
            SendMessage("已填入默认数据");
        }

        private void SendMessage(string text)
        {
            OutText += "[" + DateTime.Now + "] " + text + "\n";
        }
    }
}
